package com.call.utils;

public class MyBase64 {
	private static char base64[] = {
			'A','B','C','D','E','F','G','H','I','J','K','L','M',
			'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
			'a','b','c','d','e','f','g','h','i','j','k','l','m',
			'n','o','p','q','r','s','t','u','v','w','x','y','z',
			'0','1','2','3','4','5','6','7','8','9','+','/'
	};
	public static String encode(byte[] data)
	{
		int len = data.length*8;
		String padding = "";
		int left = 0;
		int leftData = 0;
		String res = "";
		for (int i = 0; i < data.length; i++) {
			int nowByte = data[i];
			while (nowByte < 0) {
				nowByte += 256;
			}
			leftData = (leftData << (6-left)) + (nowByte >> (8 - (6 - left)));
			res += base64[leftData];
			left = 8 - (6 - left);
			leftData = nowByte & ((1 << left) - 1);
			if (left == 6)
			{
				res += base64[leftData];
				left = 0;
				leftData = 0;
			}
		}
		if (left == 2) {
			padding = "==";
			leftData = leftData << 4;
			res += base64[leftData];
			res += padding;
		} else if (left == 4) {
			padding = "=";
			leftData = leftData << 2;
			res += base64[leftData];
			res += padding;
		}
		return res;
	}
	private static int getBase64CharIndex(char c) {
		if (c >= 'A' && c <= 'Z') {
			return c - 'A';
		} else if (c >= 'a' && c <= 'z') {
			return c - 'a' + 26;
		} else if (c >= '0' && c <= '9') {
			return c - '0' + 52;
		} else if (c == '+') {
			return 62;
		}
		return 63;
	}
	public static byte[] decode(String data) {
		int len = data.length();
		int padLen = 0;
		if (data.charAt(len - 1) == '=') {
			padLen = 2;
			len--;
			if (data.charAt(len - 1) == '=') {
				padLen = 4;
				len--;
			}
		}
		int byteLen = (len * 6 - padLen) / 8;
		byte[] res = new byte[byteLen];
		int left = 0;
		int leftData = 0;
		int dataPos = 0;
		for (int i = 0; i < byteLen; i++) {
			while (left < 8) {
				leftData = leftData << 6;
				leftData += getBase64CharIndex(data.charAt(dataPos++)); 
				left += 6;
			}
			res[i] = (byte) (leftData >> (left - 8));
		}
		return res;
	}
}
